﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Roguelike
{
    // Movement flags applied to creatures and tiles
    public enum moveFlag { walk, fly, swim }

    public class MovementManager
    {
        /// <summary>
        /// Moves an entity one tile in a direction if that move is valid
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="direction"></param>
        public void Move(Mob mob, input direction)
        {
            int oldX = mob.x;
            int oldY = mob.y;

            int[] newXY = GetNewXY(oldX, oldY, direction);
            int newX = newXY[0];
            int newY = newXY[1];

            // If the mob can legally move to the desired location, move it
            if (TestMoveValidity(mob, newX, newY) == true)
            {
                // Set mob's x and y variables to the new location
                mob.x = newX;
                mob.y = newY;
                Singleton<ScreenManager>.instance.UpdateGraphicsMap(mob, oldX, oldY, newX, newY);
            }
        }

        /// <summary>
        /// Tests if a desired move by a mob is legal
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        private bool TestMoveValidity(Mob mob, int x, int y)
        {
            // Get a list of what movement types are legal through the desired tile
            List<moveFlag> tilePassFlags = Singleton<TileManager>.instance.GetXYPassFlags(x, y);

            bool validMove = false;

            // If there's an entity at the x, y coordinates and this mob can't pass over that entity, return false
            // TODO: refactor and replace with combat handling at some point
            if (Singleton<GameManager>.instance.TestIfEntityAtXY(x, y) == true)
            {
                if (Singleton<GameManager>.instance.GetEntityAtXY(x, y).OtherCanPassOver(mob) == false)
                {
                    return validMove;
                }
            }

            // If the mob can legally move through the tile, set validMove to true
            foreach (moveFlag flag in mob.moveTypes)
            {
                if (tilePassFlags.Contains(flag) == true)
                {
                    validMove = true;
                }
            }

            return validMove;
        }

        /// <summary>
        /// Calculates new X and Y coordinates for one move based on a movement direction
        /// </summary>
        /// <param name="oldX"></param>
        /// <param name="oldY"></param>
        /// <param name="direction"></param>
        /// <returns></returns>
        private int[] GetNewXY(int oldX, int oldY, input direction)
        {
            int newX = oldX;
            int newY = oldY;

            if (direction == input.up)
            {
                newY = oldY - 1;
            }
            else if (direction == input.down)
            {
                newY = oldY + 1;
            }
            else if (direction == input.left)
            {
                newX = oldX - 1;
            }
            else if (direction == input.right)
            {
                newX = oldX + 1;
            }

            int[] newXY = {newX, newY};
            return newXY;
        }
    }
}
